package com.christophpurrer.dep;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;

/**
 * Partially based on:
 * http://stackoverflow.com/questions/2317428/android-i-want-to-shake-it
 * 
 * @author Christoph Purrer
 * 
 */
public class AccelerometerListener implements SensorEventListener {

	private SensorManager sensorManager;
	private List<Sensor> sensors;
	private Sensor sensor;
	private long lastUpdate = -1;
	private long currentTime = -1;
	private Context context;
	private Timer timer;
	private int shakes;
	private static final Handler mHandler = new Handler();

	private float last_x, last_y, last_z;
	private float current_x, current_y, current_z, currenForce;
	private static final int FORCE_THRESHOLD = 500;
	private final int DATA_X = SensorManager.DATA_X;
	private final int DATA_Y = SensorManager.DATA_Y;
	private final int DATA_Z = SensorManager.DATA_Z;

	public AccelerometerListener(Context context) {
		SensorManager sensorService = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);

		this.sensorManager = sensorService;
		if (sensorService == null)
			return;

		this.sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
		if (sensors.size() > 0) {
			sensor = sensors.get(0);
		}

		this.context = context;
	}

	public void start() {
		if (sensor == null)
			return;

		sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
	}

	public void stop() {
		if (sensorManager == null)
			return;

		sensorManager.unregisterListener(this);
	}

	public void onAccuracyChanged(Sensor s, int valu) {

	}

	public void onSensorChanged(SensorEvent event) {

		if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
			return;

		currentTime = System.currentTimeMillis();

		if ((currentTime - lastUpdate) > 50) {
			long diffTime = (currentTime - lastUpdate);
			lastUpdate = currentTime;

			current_x = event.values[DATA_X];
			current_y = event.values[DATA_Y];
			current_z = event.values[DATA_Z];

			currenForce = Math.abs(current_x + current_y + current_z - last_x - last_y - last_z) / diffTime * 10000;

			if (currenForce > FORCE_THRESHOLD) {
				shakeDetected();
			}
			last_x = current_x;
			last_y = current_y;
			last_z = current_z;

		}
	}

	private void shakeDetected() {
		shakes++;

		if (shakes == 1) {
			if (timer != null) {
				timer.cancel();
			}

			timer = new Timer();
			timer.schedule(new TimerTask() {

				@Override
				public void run() {
					if (shakes > 3) {
						mHandler.post(new Runnable() {

							public void run() {
								// shake
							}
						});
					}

					shakes = 0;
				}
			}, 500);
		}
	}
}